package com.anuo.app.study.StudyCollections;

import com.alibaba.fastjson.JSON;
import com.anuo.app.common.utils.JsonUtil;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.shiro.crypto.hash.Hash;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import java.math.BigDecimal;
import java.util.HashSet;
import java.util.LinkedHashSet;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"classpath:spring/spring-context.xml"})
public class StudyHashSet {


    /**
     * HashSet example
     * 特点:
     * # hash实现, 无重复list, 比ArrayList更快
     * # 如果contains用的比较多, 请用HashSet,比ArrayList快很多
     */
    @Test
    public void studyHashSet() {
        //无序的(插入顺序不等于输出顺序)
        HashSet<String> stringHashSet = new HashSet<>();
        stringHashSet.add("jk");
        stringHashSet.add("jk");
        stringHashSet.add("anuo");
        stringHashSet.add("is");
        stringHashSet.add("a coder");
        for (String s : stringHashSet) {
            //System.out.println(s);
        }
        //有序的(插入顺序等于输出顺序)
        LinkedHashSet<String> stringLinkedHashSet = new LinkedHashSet<>();
        stringLinkedHashSet.add("jk");
        stringLinkedHashSet.add("jk");
        stringLinkedHashSet.add("anuo");
        stringLinkedHashSet.add("is");
        stringLinkedHashSet.add("a coder");

        for (String s : stringLinkedHashSet) {
            System.out.println(s);
        }

    }

    /**
     * 在hashset 中添加不重复的obj
     * 重写 hashCode 和 equals 方法即可
     */
    @Test
    public void eliminateDuplicateInHashSet() {
        Person personA = new Person();
        personA.setName("jk");
        personA.setAge(28);

        Person personB = new Person();
        personB.setName("zs");
        personB.setAge(22);

        Person personC = new Person();
        personC.setName("jk");
        personC.setAge(28);

        HashSet<Person> hashSetList = new HashSet<>();
        hashSetList.add(personA);
        hashSetList.add(personB);
        hashSetList.add(personC);

        for (Person person : hashSetList) {
            System.out.println(JsonUtil.toJsonPretty(person));
        }
    }

    /**
     * 重写 hashCode 和 equals 方法的实体类
     * 参考: https://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java
     */
    private static class Person {
        private String name;
        private int age;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        @Override
        public int hashCode() {
            return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
                    // if deriving: appendSuper(super.hashCode()).
                            append(name).
                            append(age).
                            toHashCode();
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Person))
                return false;
            if (obj == this)
                return true;

            Person rhs = (Person) obj;
            return new EqualsBuilder().
                    // if deriving: appendSuper(super.equals(obj)).
                            append(name, rhs.name).
                            append(age, rhs.age).
                            isEquals();
        }


    }
}
